{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# भाग 2: फेडरेटेड लर्निंगचा(Federated Learning) परिचय\n",
    "\n",
    "आधीच्या विभागात, आपण पॉइंटरटेन्सर(PointerTensor) विषयी शिकलो, जे डीप लर्निंग जपण्यासाठी आपल्याला गोपनीयता आवश्यक असणारी मूलभूत सुविधा तयार करतात. या विभागात, फेडरेटेड लर्निंग(Federated Learning), डीप लर्निंग अल्गोरिदम जपणारी आमची पहिली गोपनीयता कशी अंमलात आणायची या मूलभूत साधनांचा कसा उपयोग करावा ते पाहूया .\n",
    "\n",
    "लेखक:\n",
    "- Andrew Trask - Twitter: [@iamtrask](https://twitter.com/iamtrask)\n",
    "\n",
    "अनुवादक/संपादक:\n",
    "- Krunal Kshirsagar - Twitter: [@krunal_wrote](https://twitter.com/krunal_wrote)- Github: [@Noob-can-Compile](https://github.com/Noob-can-Compile)\n",
    "\n",
    "### फेडरेटेड लर्निंग (Federated Learning) काय आहे?\n",
    "\n",
    "डीप लर्निंग(Deep Learning) मॉडेल्सना प्रशिक्षण(Train) देण्याचा हा एक सोपा आणि शक्तिशाली मार्ग आहे. जर आपण प्रशिक्षण डेटाबद्दल(Training Data) विचार केला तर तो नेहमीच कोणत्या ना कोणत्या संग्रह प्रक्रियेचा परिणाम असतो. लोक (डिव्हाइसद्वारे) वास्तविक जगात इव्हेंट रेकॉर्ड करून डेटा व्युत्पन्न करतात. सामान्यत:, हा डेटा एकल, मध्यवर्ती ठिकाणी एकत्रित केला जातो जेणेकरून आपण मशीन लर्निंग(Machine Learning) मॉडेलला प्रशिक्षित(Train) करू शकता. फेडरेटेड लर्निंग(Federated Learning) हे त्याचा डोक्यावर ठेवतं!\n",
    "\n",
    "मॉडेलमध्ये प्रशिक्षण डेटा(Training Data) (मध्यवर्ती सर्व्हर) आणण्याऐवजी, आपण मॉडेलला प्रशिक्षण डेटावर(Training Data) आणता (जिथे मिळेल तिथे).\n",
    "\n",
    "कल्पना अशी आहे की ज्याच्याकडे डेटा आहे त्याच्याकडे केवळ कायमची कॉपी राहू देते आणि अशा प्रकारे ज्याच्याकडे त्यात प्रवेश करण्याची परवानगी आहे, त्याच्यावर नियंत्रण राखते.\n",
    "\n",
    "खूप मस्त आहेना? (Pretty cool, eh)?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# विभाग २.१ - फेडेरटेड लर्निंगचे(Federated Learning) एक बनावट उदाहरण\n",
    "\n",
    "चला एक बनावट मॉडेलला केंद्रीकृत(centralized) मार्गाने प्रशिक्षण(Training) देऊन प्रारंभ करूया. मॉडेल्स मिळतात तशी ही साधारण गोष्ट आहे. आम्हाला प्रथम आवश्यकः\n",
    "\n",
    "- एक बनावट डाटासेट (a toy dataset)\n",
    "- एक मॉडेल (a model)\n",
    "- डेटाला फिट करण्यासाठी मॉडेलला प्रशिक्षण देण्याचे काही मूलभूत प्रशिक्षण तर्कशास्त्र(some basic training logic for training a model to fit the data.).\n",
    "\n",
    "\n",
    "टीपः जर हे एपीआय(API) आपल्याला अपरिचित असेल तर - [fast.ai](http://fast.ai) वर जा आणि या ट्यूटोरियलमध्ये पुढे जाण्यापूर्वी त्यांचा अभ्यासक्रम घ्या."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "from torch import nn\n",
    "from torch import optim"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# A Toy Dataset\n",
    "data = torch.tensor([[0,0],[0,1],[1,0],[1,1.]], requires_grad=True)\n",
    "target = torch.tensor([[0],[0],[1],[1.]], requires_grad=True)\n",
    "\n",
    "# A Toy Model\n",
    "model = nn.Linear(2,1)\n",
    "\n",
    "def train():\n",
    "    # Training Logic\n",
    "    opt = optim.SGD(params=model.parameters(),lr=0.1)\n",
    "    for iter in range(20):\n",
    "\n",
    "        # 1) erase previous gradients (if they exist)\n",
    "        opt.zero_grad()\n",
    "\n",
    "        # 2) make a prediction\n",
    "        pred = model(data)\n",
    "\n",
    "        # 3) calculate how much we missed\n",
    "        loss = ((pred - target)**2).sum()\n",
    "\n",
    "        # 4) figure out which weights caused us to miss\n",
    "        loss.backward()\n",
    "\n",
    "        # 5) change those weights\n",
    "        opt.step()\n",
    "\n",
    "        # 6) print our progress\n",
    "        print(loss.data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "सर्व केल्यानंतर, तुम्ही पाहुच शकतात! आपण पारंपारिक पद्धतीने मूलभूत मॉडेलचे प्रशिक्षण दिले आहे. आपला सर्व डेटा आपल्या स्थानिक मशीनमध्ये जमा केला जातो आणि आपण आपला मॉडेल अपडेट करण्यासाठी वापरु शकतो. फेडरेटेड लर्निंग (Federated Learning) मात्र तसे करत नाही. तर, या फेडरेतेड लर्निंगच्या मार्गाचे (Federated Learning way) उदाहरण घेऊ.\n",
    "\n",
    "\n",
    "तर, आपल्याला काय आवश्यक आहे:\n",
    "\n",
    "- काही कामगार तयार करा.\n",
    "- प्रत्येक कार्यकर्त्यावर प्रशिक्षण डेटा(Training Data) पॉईंटर्स (Pointers) मिळवा\n",
    "- संघीय शिक्षण (Federated Learning) करण्यासाठी प्रशिक्षण लॉजिक (Training Logic) अद्यतनित केले.\n",
    "\n",
    "    नवीन प्रशिक्षण चरण:\n",
    "    - मॉडेलला बरोबर कार्यकर्त्याकडे (worker) पाठवा\n",
    "    - तेथे असलेल्या डेटावर ट्रेन करा\n",
    "    - मॉडेल परत मिळवा आणि पुढील कर्मचार्‍यांसह (worker) पुनरावृत्ती करा"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import syft as sy\n",
    "hook = sy.TorchHook(torch)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# create a couple workers\n",
    "\n",
    "bob = sy.VirtualWorker(hook, id=\"bob\")\n",
    "alice = sy.VirtualWorker(hook, id=\"alice\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# A Toy Dataset\n",
    "data = torch.tensor([[0,0],[0,1],[1,0],[1,1.]], requires_grad=True)\n",
    "target = torch.tensor([[0],[0],[1],[1.]], requires_grad=True)\n",
    "\n",
    "# get pointers to training data on each worker by\n",
    "# sending some training data to bob and alice\n",
    "data_bob = data[0:2]\n",
    "target_bob = target[0:2]\n",
    "\n",
    "data_alice = data[2:]\n",
    "target_alice = target[2:]\n",
    "\n",
    "# Iniitalize A Toy Model\n",
    "model = nn.Linear(2,1)\n",
    "\n",
    "data_bob = data_bob.send(bob)\n",
    "data_alice = data_alice.send(alice)\n",
    "target_bob = target_bob.send(bob)\n",
    "target_alice = target_alice.send(alice)\n",
    "\n",
    "# organize pointers into a list\n",
    "datasets = [(data_bob,target_bob),(data_alice,target_alice)]\n",
    "\n",
    "opt = optim.SGD(params=model.parameters(),lr=0.1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train():\n",
    "    # Training Logic\n",
    "    opt = optim.SGD(params=model.parameters(),lr=0.1)\n",
    "    for iter in range(10):\n",
    "        \n",
    "        # NEW) iterate through each worker's dataset\n",
    "        for data,target in datasets:\n",
    "            \n",
    "            # NEW) send model to correct worker\n",
    "            model.send(data.location)\n",
    "\n",
    "            # 1) erase previous gradients (if they exist)\n",
    "            opt.zero_grad()\n",
    "\n",
    "            # 2) make a prediction\n",
    "            pred = model(data)\n",
    "\n",
    "            # 3) calculate how much we missed\n",
    "            loss = ((pred - target)**2).sum()\n",
    "\n",
    "            # 4) figure out which weights caused us to miss\n",
    "            loss.backward()\n",
    "\n",
    "            # 5) change those weights\n",
    "            opt.step()\n",
    "            \n",
    "            # NEW) get model (with gradients)\n",
    "            model.get()\n",
    "\n",
    "            # 6) print our progress\n",
    "            print(loss.get()) # NEW) slight edit... need to call .get() on loss\\\n",
    "    \n",
    "# federated averaging"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## खूप छान!\n",
    "\n",
    "आणि पहा (And voilà!)\n",
    "\n",
    "आपण आता फेडरेटेड लर्निंगचा (Federated Learning) वापर करून खूप सोप्या डीप लर्निंग (Deep Learning) मॉडेलचे प्रशिक्षण (Training) घेत आहोत! आपण प्रत्येक कामगारांना (worker) मॉडेल पाठवतो, नवीन ग्रेडियंट (Gradient) व्युत्पन्न करतो आणि नंतर आपल्या स्थानिक सर्व्हरवर ग्रेडियंट (Gradient) परत आणतो जिथे आपण आपले जागतिक मॉडेल अद्यतनित करतो. या प्रक्रियेत आपण कधीही अंतर्निहित प्रशिक्षण डेटा पाहत किंवा प्रवेश करण्याची विनंती करत नाही! आपण Bob आणि Alice ची गोपनीयता जपतो !!!\n",
    "\n",
    "## या उदाहरणाच्या कमतरता\n",
    "\n",
    "तर, हे उदाहरण फेडरेट लर्निंगची  (Federated Learning) एक छान ओळख आहे, तरीही अद्याप त्यात काही प्रमुख कमतरता आहेत. विशेष म्हणजे, जेव्हा आपण `model.get () call करतो आणि Bob किंवा Alice कडून अद्ययावत केलेले मॉडेल प्राप्त करतो तेव्हा आपण Bob आणि Alice च्या प्रशिक्षण डेटाबद्दल त्यांचे ग्रेडियंट (Gradient) पाहून बरेच काही शिकू शकतो. काही प्रकरणांमध्ये, आपण त्यांचा प्रशिक्षण डेटा (Training Data) अगदी पुनर्संचयित करू शकतो!\n",
    "\n",
    "तर,आता उरले काय करायला? बरं, लोक वापरत असलेली पहिली रणनीती हे मध्यवर्ती सर्व्हरवर अपलोड करण्यापूर्वी एकाधिक व्यक्तींच्या ग्रेडियंटची (Gradient) सरासरी काढा. या धोरणाला, तथापि, पॉइंटरटेन्सर वस्तूंचा (PointerTensor Object) आणखी काही अत्याधुनिक वापर आवश्यक आहे. तर, पुढील विभागात, आपण अधिक प्रगत पॉईंटर (Pointer) कार्यक्षमतेबद्दल जाणून घेण्यासाठी थोडा वेळ घेणार आहोत आणि मग आपण हे फेडरेटेड लर्निंगचे (Federated Learning) उदाहरण सुधारित करू.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# अभिनंदन !!! - समुदायात सामील होण्याची वेळ आली!\n",
    "\n",
    "\n",
    "हे नोटबुक ट्यूटोरियल पूर्ण केल्याबद्दल अभिनंदन! आपण याचा आनंद घेत असल्यास आणि एआय(AI) आणि एआय सप्लाय चेन  (डेटा) च्या विकेंद्रित(Decentralized) मालकीच्या गोपनीयतेच्या संरक्षणाच्या दिशेने चळवळीत सामील होऊ इच्छित असाल तर आपण हे खालील प्रकारे करू शकता!\n",
    "\n",
    "### Pysyft ला Github वर Star करा!\n",
    "\n",
    "आमच्या समुदायाला मदत करण्याचा सर्वात सोपा मार्ग म्हणजे फक्त गिटहब(GitHub) रेपो(Repo) तारांकित(Star) करणे! हे आम्ही तयार करीत असलेल्या छान साधनांविषयी जागरूकता वाढविण्यास मदत करते.\n",
    "\n",
    "- [Star PySyft](https://github.com/OpenMined/PySyft)\n",
    "\n",
    "### आमच्या Slack मध्ये सामील व्हा!\n",
    "\n",
    "\n",
    "नवीनतम प्रगतीवर अद्ययावत राहण्याचा उत्तम मार्ग म्हणजे आमच्या समुदायामध्ये सामील होणे! आपण [http://slack.openmined.org](http://slack.openmined.org) येथे फॉर्म भरुन तसे करू शकता.\n",
    "\n",
    "### एका कोड प्रोजेक्टमध्ये सामील व्हा!\n",
    "\n",
    "आमच्या समुदायामध्ये योगदानाचा उत्तम मार्ग म्हणजे कोड योगदानकर्ता बनणे! कोणत्याही वेळी आपण (PySyft GitHub Issues Page) वर  जाऊ शकता आणि \"Project\" साठी फिल्टर करू शकता. हे आपण कोणत्या प्रकल्पांमध्ये सामील होऊ शकता याबद्दल विहंगावलोकन देणारी सर्व उच्च स्तरीय तिकिटे दर्शवेल! आपण एखाद्या प्रकल्पात सामील होऊ इच्छित नसल्यास, परंतु आपण थोडं कोडिंग करू इच्छित असाल तर आपण \"good first issues\" म्हणून चिन्हांकित गिटहब(GitHub) अंक शोधून आणखी \"one off\" मिनी-प्रकल्प(mini project) शोधू शकता.\n",
    "\n",
    "- [PySyft Projects](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3AProject)\n",
    "- [Good First Issue Tickets](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n",
    "\n",
    "### दान करा\n",
    "\n",
    "आपल्याकडे आमच्या कोडेबेसमध्ये योगदान देण्यास वेळ नसल्यास, परंतु तरीही आपल्याला समर्थन द्यावयाचे असल्यास आपण आमच्या मुक्त संग्रहात बॅकर देखील होऊ शकता. सर्व देणगी आमच्या वेब होस्टिंग आणि हॅकॅथॉन आणि मेटअप्स सारख्या इतर सामुदायिक खर्चाकडे जातात!\n",
    "\n",
    "[OpenMined's Open Collective Page](https://opencollective.com/openmined)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}